package fr.jade.resources.jetty;

import java.util.Map;

import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.bio.SocketConnector;
import org.mortbay.jetty.servlet.ServletHandler;
import org.objectweb.fractal.api.NoSuchInterfaceException;
import org.objectweb.fractal.api.control.IllegalBindingException;
import org.objectweb.fractal.api.control.IllegalLifeCycleException;
import org.objectweb.fractal.api.control.LifeCycleController;

import fr.jade.base.JadeBaseComponent;
import fr.jade.fraclite.api.control.NoSuchAttributeException;
import fr.jade.resources.api.HttpConnector;
import fr.jade.resources.api.Servlets;

public class JettyWrapper extends JadeBaseComponent implements HttpConnector, LifeCycleController {

  // Attributes
  protected static final String portAttName = "port";
  protected int port;
  
  protected static final String[] listAtt = {portAttName};
  
  // Bindings
  protected static final String webAppItfName = "webapp";
  protected Servlets webApp;
  
  protected static final String[] listItf = {webAppItfName};
  
  
  protected Server server;
  
  public JettyWrapper(){
    server = new Server();
  }
  
  @Override
  public String getFcState() {
    return server.isStarted()?STARTED:STOPPED;
  }

  @Override
  public void startFc() throws IllegalLifeCycleException {
    if(server.isStopped()){
      Connector connector=new SocketConnector();
      connector.setPort(port);
      server.setConnectors(new Connector[]{connector});
           
      ServletHandler handler=new ServletHandler();
      server.setHandler(handler);
      
      Map<String, String> servlets = webApp.getServletsMapping();
      for(Map.Entry<String, String> e : servlets.entrySet()){
        handler.addServletWithMapping(e.getKey(), e.getValue());
      }
    
      try {
        server.start();
        //server.join();
      } catch (Exception e) {
        throw new IllegalLifeCycleException(e.toString());
      }
    }
  }

  @Override
  public void stopFc() throws IllegalLifeCycleException {
    if(server.isStarted()){
      try {
        server.stop();
        server.destroy();
      } catch (Exception e) {
        throw new IllegalLifeCycleException(e.toString());
      }  
    }
  }

  @Override
  public void bindFc(String itfName, Object itfValue) throws NoSuchInterfaceException, IllegalBindingException, IllegalLifeCycleException {
    if(itfName.equals(webAppItfName)){
      webApp = (Servlets)itfValue;
    }else{
      super.bindFc(itfName, itfValue);
    }
  }

  @Override
  public void unbindFc(String itfName) throws NoSuchInterfaceException, IllegalBindingException, IllegalLifeCycleException {
    if(itfName.equals(webAppItfName)){
      webApp = null;
    }else{
      super.unbindFc(itfName);
    }
  }
  
  @Override
  public Object lookupFc(String itfName) throws NoSuchInterfaceException {
    if(itfName.equals(webAppItfName)){
      return webApp;
    }else{
      return super.lookupFc(itfName);
    }
  }
  
  @Override
  public String[] listFc() {
    return super.concat(listItf, super.listFc());
  }

  @Override
  public String getAttribute(String name) throws NoSuchAttributeException {
    if(name.equals(portAttName)){
      return Integer.toString(port);
    }else{
      return super.getAttribute(name);
    }
  }
  
  @Override
  public String[] listFcAtt() {
    return super.concat(listAtt, super.listFcAtt());
  }

  @Override
  public void setAttribute(String name, String value) throws NoSuchAttributeException {
    if(name.equals(portAttName)){
      port = Integer.parseInt(value);
    }else{
      super.setAttribute(name, value);
    }
  }

  @Override
  public int getPort(){
    return port;
  }
}
